package com.distribute.core.notify.redis.redisson;

import cn.hutool.core.util.StrUtil;
import com.distribute.common.Constants;
import com.distribute.common.NotifyPluginType;
import com.distribute.core.annotation.DLCCell;
import com.distribute.core.constants.CacheConstants;
import com.distribute.core.constants.LocalCacheConstants;
import com.distribute.core.core.BaseNotifyMessage;
import com.distribute.core.init.AbstractNotifyComponent;
import com.distribute.core.notify.DLCNotify;
import com.distribute.core.notify.redis.DLCRedisCenter;
import com.distribute.core.utils.SpringContextUtils;
import org.redisson.api.RTopic;
import org.redisson.api.RedissonClient;
import org.redisson.codec.SerializationCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;

/**
 * redis 通知组件 初始化
 * 初始化 channel
 *
 * @author chennengcheng
 * @date 2021-09-17 17:19
 * @remark
 */

public class RedissonNotifyComponent extends AbstractNotifyComponent {

    private static final Logger log = LoggerFactory.getLogger(RedissonNotifyComponent.class);

    @Override
    public void init() {
        // 设置插件类型为 redis
        LocalCacheConstants.setNotifyPluginType(NotifyPluginType.REDIS);
        // 初始化 redis topic 通知对象
        RedissonClient redissonClient = SpringContextUtils.getBean(RedissonClient.class);
        // 将 mode_prefix 做 topic
        CacheConstants.CELLS_MAP.keySet().parallelStream().forEach(className -> {
            DLCCell dlcCell = CacheConstants.CELLS_MAP.get(className);
            String modelPrefix = dlcCell.modelPrefix();
            String model = dlcCell.model();
            String topicName = Constants.DLC_CACHE + StrUtil.COLON + modelPrefix + StrUtil.COLON + model;
            log.info("Redisson 正在初始化 redis 订阅 topicChannel： " + topicName);
            RTopic topic = redissonClient.getTopic(topicName, new SerializationCodec());
            topic.addListener(BaseNotifyMessage.class, new RedssionNotifyMessageListener());
        });
    }

    @Bean
    public DLCNotify notifyCacheUpdateImpl(DLCRedisCenter<RedissonClient> dlcRedisCenter){
        RedissonClient redissonClient = dlcRedisCenter.getRedisClient();
        return new RedissonTopicNotifyImpl(redissonClient);
    }
}
